#页面父类：web自动化测试的页面父类
'''
    1.通用数据
    2.通用的操作
'''

import autoit,time
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains

class PageBase(object):
    def __init__(self,driver,base_url):
        self.driver=driver
        self.base_url=base_url

    #UI通用操作：打开某网页
    def open(self,pathUrl):#类似"/simple/login"
        self.driver.get(self.base_url+pathUrl)

    #UI通用操作：根据元素的定位特征loc来定位元素
    #loc参数：类似："id","userA"
    def find_element(self,loc,isDebug=False):
        by=loc[0]
        value=loc[1]
        ele=self.driver.find_element(by,value)
        if isDebug:
            style = "background: green; border: 2px solid red;color: red;"
            self.driver.execute_script("arguments[0].setAttribute('style',arguments[1]);", ele, style)
        return ele

    def find_elements(self, loc):
        by = loc[0]
        value = loc[1]
        return self.driver.find_elements(by, value)


    #UI通用操作：点击元素：//元素点击
    def click(self,loc,isDebug=False):
        ele=self.find_element(loc,isDebug)
        ele.click()

    # 适合控件：文本框、密码框、多行文本框
    # UI通用操作：给某元素loc输入某数据data
    def input(self,loc,data,isDebug=False):
        ele=self.find_element(loc,isDebug)
        ele.send_keys(data)

    # 对文本框/密码框/多行文本框进行清空并输入数据：考虑到了失去焦点事件
    def clearAndInput(self,loc,data,isDebug=False,isLoseFucus=False):
        ele = self.find_element(loc, isDebug)
        if isLoseFucus:
            ele.send_keys(Keys.CONTROL, 'a')  # ctrl+A
            ele.send_keys(Keys.BACK_SPACE)
        else:
            ele.clear()
        ele.send_keys(data)


    #获取某元素的文本内容/某属性的值。
    def getEleAttrOrText(self,loc,type="text",attrName=None,isStrip=True):
        ele = self.find_element(loc)
        if type=="text":
            textData=ele.text
            if isStrip:
                return textData.strip()
            return textData
        else:
            data=ele.get_attribute(attrName)
            if isStrip:
                return data.strip()
            return data

    #判断某元素loc是否在当前页面存在
    def isExists(self,loc):
        try:
            self.driver.find_element(loc[0],loc[1])
            return True
        except Exception:
            return False

    #适合控件：单选按钮
    #功能：选中某选项
    def radio_click(self,attrName,targetOptionValue):
        ele=self.driver.find_element_by_css_selector(f"input[type='radio'][name='{attrName}'][value='{targetOptionValue}']")
        ele.click()

    #适合控件：复选框
    #功能：全选
    def checkbox_AllSelect(self,attrName):
        eles = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in eles:
            status = x.is_selected()
            if not status:
                x.click()

    # 适合控件：复选框
    # 功能：全不选
    def checkbox_AllNotSelect(self,attrName):
        eles = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in eles:
            status = x.is_selected()
            if status:
                x.click()

    # 适合控件：复选框
    # 功能：反选
    def checkbox_reverseSelect(self,attrName):
        eles=self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in eles:
            x.click()

    # 适合控件：复选框
    # 功能：选指定的n个选项：0个  1个 2个
    def checkbox_selectN(self,attrName,targetOptionValue):#"" "dalanqiu,wanyouxi"
        eles = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in eles:
            attrValue = x.get_attribute("value")  # "dalanqiu" "tizuqiu" "wanyouxi"
            status = x.is_selected()
            if attrValue in targetOptionValue:
                if not status:
                    x.click()
            else:
                if status:
                    x.click()



    #适合控件：下拉列表
    #功能：选中某选项
    def select_click(self,attrName,data,type="text"):
        ele_select = self.driver.find_element_by_css_selector(f"select[name='{attrName}']")
        haha = Select(ele_select)
        if type=="text":
            haha.select_by_visible_text(data)
        elif type=="index":
            haha.select_by_index(data)
        else:
            haha.select_by_value(data)

    #适合控件：日期类
    #功能：输入某日期值：支持：年月日、年月日时分秒
    def input_date(self,loc,riqi,type="js",isReadOnly=False):
        ele=self.find_element(loc)
        if type=="js":
            if isReadOnly:
                self.driver.execute_script("arguments[0].removeAttribute('readonly')", ele)
            self.driver.execute_script("arguments[0].value=arguments[1]", ele, riqi)
        else:
            if isReadOnly:
                self.driver.execute_script("arguments[0].removeAttribute('readonly')", ele)
            ele.send_keys(riqi)


    #适合控件：文件框。文件上传。
    #功能：上传N个文件/目录。支持：0个 1个 2个
    #filePath="" "C:/A/1.png" "C:/A/1.png,D:/A/2.jpg"
    def uploadFileOrDir(self,loc,filePath,type="autoIT"):
        if filePath == "" or filePath == None:
            return

        if type=="autoIT":
            # 实现步骤1
            ele =self.find_element(loc)
            ActionChains(self.driver).click(ele).perform()
            time.sleep(2)

            # 实现步骤2和步骤3
            newFilePath = ""
            a = filePath.split(",")  # ["C:/A/1.png","C:/A/2.jpg"]
            for x in a:
                newFilePath += '"' + x + '" '

            newFilePath = newFilePath.replace("/", "\\")
            autoit.win_wait("打开", 10)
            autoit.control_send("打开", "Edit1", newFilePath)
            autoit.control_click("打开", "Button1")
        else:
            newFilePath = filePath.replace(",", "\n")
            ele = self.find_element(loc)
            ele.send_keys(newFilePath)

    # 处理JS三种弹出框
    # 获取三种JS弹出框的文本内容
    def getTextForJsTanCuKuan(self):
        return self.driver.switch_to.alert.text

    # 点击三种JS弹出框的“确定”按钮
    def acceptForJsTanCuKuan(self):
        self.driver.switch_to.alert.accept()

    # 点击三种JS弹出框的“取消”按钮
    def dismissForJsTanCuKuan(self):
        self.driver.switch_to.alert.dismiss()

    # 为JS的prompt弹出框输入文本
    def inputJsTanCuKuan(self, data):
        self.driver.switch_to.alert.send_keys(data)


    # iframe框架相关处理
    # 切换到某iframe
    def switch_iframe(self, data,type="loc"):
        if type=="loc":
            ele=self.find_element(data)
            self.driver.switch_to.frame(ele)
        else:
            self.driver.switch_to.frame(data)#name属性、id属性、int类型下标(从0开始)


    # 切换到主iframe
    def switch_defaultIframe(self):
        self.driver.switch_to.default_content()

    # 鼠标操作的相关处理
    # 函数功能：鼠标单击某元素loc
    def mouse_click(self, loc, idDebug=False):
        ele = self.find_element(loc, idDebug)
        ActionChains(self.driver).click(ele).perform()

    # 函数功能：鼠标双击某元素loc
    def mouse_dbclick(self, loc, idDebug=False):
        ele = self.find_element(loc, idDebug)
        ActionChains(self.driver).double_click(ele).perform()

    # 函数功能：鼠标悬停在某元素loc
    def mouse_moveToEle(self, loc, idDebug=False):
        ele = self.find_element(loc, idDebug)
        ActionChains(self.driver).move_to_element(ele).perform()

    # 函数功能：滑动垂直滚动条到最底部
    def scrollToFloor(self):
        js1 = "window.scrollTo(0,10000)"
        self.driver.execute_script(js1)

    # 网页截图
    def savePng1(self, filePath):
        self.driver.get_screenshot_as_file(filePath)

    def savePng2(self, fileName):
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")

    def savePng3(self, serviceName, key):
        fileName = serviceName + "_" + key + "_" + time.strftime("%Y%m%d%H%M%S")
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")
        return fileName  # "登录_K001_20250605100314"

    # 切换标签页/切换窗口:支持：下标切换、目标窗口的标题切换、目标窗口的url切换
    # 形参n是第几个窗口。n从0开始.-1：最新打开窗口
    def switch_windowByIndex(self, type="index", data=-1):
        if type == "index":
            self.driver.switch_to.window(self.driver.window_handles[data])
        elif type == "title":
            moren_handler = self.driver.current_window_handle
            flag = True
            allWindows = self.driver.window_handles
            for one in allWindows:
                self.driver.switch_to.window(one)
                currentTitle = self.driver.title
                if data in currentTitle:
                    flag = False
                    break
                time.sleep(1)
            if flag:
                self.driver.switch_to.window(moren_handler)
        else:
            moren_handler = self.driver.current_window_handle
            flag = True
            allWindows = self.driver.window_handles
            for one in allWindows:
                self.driver.switch_to.window(one)
                currentUrl = self.driver.current_url
                if data in currentUrl:
                    flag = False
                    break
                time.sleep(1)
            if flag:
                self.driver.switch_to.window(moren_handler)



